#include <iostream>
#include <functional>

using std::cout;
using std::endl;
using std::bind;
using std::function;

int add(int x, int y)
{
    cout << "int add(int, int)" << endl;
    return x + y;
}

int func(int x, int y, int z)
{
    cout << "int func(int, int, int)" << endl;
    return x * y * z;
}

class Example
{
public:
    //Example * this
    int add(int x, int y)
    {
        cout << "int Example::add(int, int)" << endl;
        return x + y;
    }

    int data = 100;//C++11语法特性
};

void test()
{
    //函数的类型（函数的标签）:
    //函数的返回类型 + 参数列表(参数的个数、类型、顺序)
    //
    //bind的特点：可以改变函数类型（特定的，可以改变函数的参数
    //个数）
    //
    //add特点：int(int, int)
    //add经过bind绑定之后，将两个参数都传递了，所以返回的结果
    //应该是int()
    /* auto f = bind(add, 1, 3); */
    function<int()> f = bind(add, 1, 3);
    cout << "f() = " << f() << endl;

    cout << endl;
    //func特点：int(int, int, int)
    //f2:int()
    function<int()> f2 = bind(&func, 3, 5, 6);
    cout << "f2() = " << f2() << endl;

    cout << endl;
    Example ex;
    //add:int(Example *, int, int)
    //f3:int()
    function<int()> f3 = bind(&Example::add, &ex, 10, 30);
    cout << "f3() = " << f3() << endl;

    cout << endl;
    using namespace std::placeholders;
    //占位符
    //func的特点：int(int, int, int)
    //f4:int(int, int)
    function<int(int, int)> f4 = bind(func, _1, _2, 30);
    cout << "f4(10, 20) = " << f4(10, 20) << endl;

    cout << endl;
    function<int()> f5 = bind(&Example::data, &ex);
    cout << "f5() = " << f5() << endl;
}

void test2()
{
    Example ex;
    function<int()> f = bind(&Example::add, &ex, 10, 30);
    cout << "f() = " << f() << endl;

    cout << endl;
    function<int()> f2 = bind(&Example::add, ex, 10, 30);
    cout << "f2() = " << f2() << endl;
}

int main(int argc, char *argv[])
{
    test2();
    return 0;
}

